// MCP 服务器示例 - 用于测试浏览器插件中的 MCP 功能
// 运行方式: node mcp-server-example.js

const express = require('express');
const cors = require('cors');
const app = express();
const PORT = 3000;

// 中间件
app.use(cors());
app.use(express.json());

// 模拟工具定义
const tools = [
  {
    name: 'web_search',
    description: '搜索网页内容',
    parameters: {
      query: { type: 'string', description: '搜索关键词' },
      maxResults: { type: 'number', description: '最大结果数', default: 10 }
    }
  },
  {
    name: 'get_time',
    description: '获取当前时间',
    parameters: {}
  },
  {
    name: 'calculate',
    description: '执行数学计算',
    parameters: {
      expression: { type: 'string', description: '数学表达式' }
    }
  },
  {
    name: 'file_operations',
    description: '文件操作（模拟）',
    parameters: {
      operation: { type: 'string', description: '操作类型: read/write/list' },
      path: { type: 'string', description: '文件路径' },
      content: { type: 'string', description: '文件内容（写入时使用）' }
    }
  }
];

// 健康检查端点
app.get('/health', (req, res) => {
  res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});

// 获取工具列表
app.get('/tools', (req, res) => {
  res.json({ tools });
});

// 获取特定工具信息
app.get('/tools/:name', (req, res) => {
  const tool = tools.find(t => t.name === req.params.name);
  if (!tool) {
    return res.status(404).json({ error: 'Tool not found' });
  }
  res.json({ tool });
});

// 调用工具
app.post('/tools/:name/call', (req, res) => {
  const toolName = req.params.name;
  const args = req.body.arguments || {};
  
  console.log(`调用工具: ${toolName}`, args);
  
  try {
    let result;
    
    switch (toolName) {
      case 'web_search':
        result = handleWebSearch(args);
        break;
      case 'get_time':
        result = handleGetTime(args);
        break;
      case 'calculate':
        result = handleCalculate(args);
        break;
      case 'file_operations':
        result = handleFileOperations(args);
        break;
      default:
        return res.status(404).json({ 
          error: `Unknown tool: ${toolName}` 
        });
    }
    
    res.json({ content: result });
  } catch (error) {
    console.error(`工具调用错误 ${toolName}:`, error);
    res.status(500).json({ 
      error: error.message || 'Tool execution failed' 
    });
  }
});

// 工具实现函数

function handleWebSearch(args) {
  const { query, maxResults = 10 } = args;
  
  if (!query) {
    throw new Error('Query parameter is required');
  }
  
  // 模拟搜索结果
  const mockResults = [
    {
      title: `${query} - 官方文档`,
      url: `https://docs.example.com/${query.toLowerCase()}`,
      snippet: `关于 ${query} 的官方文档和使用指南...`
    },
    {
      title: `${query} 入门教程`,
      url: `https://tutorial.example.com/${query.toLowerCase()}`,
      snippet: `学习 ${query} 的完整教程，从基础到高级...`
    },
    {
      title: `${query} GitHub 仓库`,
      url: `https://github.com/example/${query.toLowerCase()}`,
      snippet: `${query} 的开源代码仓库，包含示例和文档...`
    },
    {
      title: `${query} 社区讨论`,
      url: `https://community.example.com/${query.toLowerCase()}`,
      snippet: `${query} 相关的社区讨论和问答...`
    }
  ];
  
  return mockResults.slice(0, Math.min(maxResults, mockResults.length));
}

function handleGetTime(args) {
  return {
    timestamp: new Date().toISOString(),
    readable: new Date().toLocaleString('zh-CN'),
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    unix: Math.floor(Date.now() / 1000)
  };
}

function handleCalculate(args) {
  const { expression } = args;
  
  if (!expression) {
    throw new Error('Expression parameter is required');
  }
  
  // 简单的数学表达式计算（仅支持基本运算）
  try {
    // 安全检查：只允许数字、基本运算符和括号
    if (!/^[0-9+\-*/().\s]+$/.test(expression)) {
      throw new Error('Invalid expression: only numbers and basic operators are allowed');
    }
    
    const result = eval(expression);
    
    return {
      expression,
      result,
      type: typeof result
    };
  } catch (error) {
    throw new Error(`Calculation error: ${error.message}`);
  }
}

function handleFileOperations(args) {
  const { operation, path, content } = args;
  
  if (!operation) {
    throw new Error('Operation parameter is required');
  }
  
  switch (operation) {
    case 'read':
      if (!path) {
        throw new Error('Path parameter is required for read operation');
      }
      return {
        operation: 'read',
        path,
        content: `模拟文件内容: ${path}\n这是一个模拟的文件读取结果。`,
        size: 1024,
        lastModified: new Date().toISOString()
      };
      
    case 'write':
      if (!path || content === undefined) {
        throw new Error('Path and content parameters are required for write operation');
      }
      return {
        operation: 'write',
        path,
        bytesWritten: content.length,
        success: true,
        timestamp: new Date().toISOString()
      };
      
    case 'list':
      const basePath = path || '/';
      return {
        operation: 'list',
        path: basePath,
        files: [
          { name: 'document.txt', type: 'file', size: 1024 },
          { name: 'images', type: 'directory', size: 0 },
          { name: 'config.json', type: 'file', size: 512 },
          { name: 'backup', type: 'directory', size: 0 }
        ]
      };
      
    default:
      throw new Error(`Unsupported operation: ${operation}`);
  }
}

// 错误处理中间件
app.use((error, req, res, next) => {
  console.error('服务器错误:', error);
  res.status(500).json({ 
    error: 'Internal server error',
    message: error.message 
  });
});

// 404 处理
app.use('*', (req, res) => {
  res.status(404).json({ 
    error: 'Endpoint not found',
    path: req.originalUrl 
  });
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`MCP 测试服务器运行在 http://localhost:${PORT}`);
  console.log('可用端点:');
  console.log(`  GET  /health - 健康检查`);
  console.log(`  GET  /tools - 获取工具列表`);
  console.log(`  POST /tools/{name}/call - 调用工具`);
  console.log('');
  console.log('示例工具:');
  tools.forEach(tool => {
    console.log(`  - ${tool.name}: ${tool.description}`);
  });
});

// 优雅关闭
process.on('SIGINT', () => {
  console.log('\n正在关闭服务器...');
  process.exit(0);
});